from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

from fastapi import Depends

from recruit.adapter.stubs import StubUserGateway
from recruit.application.commands.create_user import CreateUser
from recruit.application.commands.get_user import GetUser
from recruit.application.commands.update_user import UpdateUser
from recruit.application.protocols import UoW
from recruit.domain.services.user import UserService
from recruit.presentation.user_interactor import UserInteractorFactory


class UserIOC(UserInteractorFactory):
    def __init__(
            self,
            uow: UoW = Depends(),
            gateway: StubUserGateway = Depends()
    ) -> None:
        self.uow = uow
        self.gateway = gateway
        self.service = UserService()

    @asynccontextmanager
    async def create_user(self) -> AsyncIterator[CreateUser]:
        yield CreateUser(
            uow=self.uow,
            user_db_gateway=self.gateway,
            user_service=self.service
        )

    @asynccontextmanager
    async def get_user(self) -> AsyncIterator[GetUser]:
        yield GetUser(
            user_db_gateway=self.gateway,
            user_service=self.service
        )

    @asynccontextmanager
    async def update_user(self) -> AsyncIterator[UpdateUser]:
        yield UpdateUser(
            uow=self.uow,
            user_db_gateway=self.gateway,
            user_service=self.service
        )
